package com.ocom.ugcapi.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.vo.ugcapi.GzhUserInfo;
import com.ocom.redis.util.RedisUtil;
import com.ocom.ugcapi.config.RsaConfig;
import com.ocom.ugcapi.util.RSAHelper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@Aspect
@Component
public class ServiceAspect {

    private Logger log = LoggerFactory.getLogger(ServiceAspect.class);

    @Resource
    private RedisUtil redisUtil;

    //切入点
    @Around("execution(* com.ocom.ugcapi.controller.PayController.Pay(..)) " +
            "|| execution(* com.ocom.ugcapi.controller.PayController.gzhrechageList(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.PayController.rechargeRefund(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.PayController.getRechargePayWay(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.PayController.getRechargeRule(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.PayController.StaticCodePay(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.PayController.getUserPayList(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.PayController.checkWithhold(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.PayController.AccountPay(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.CompanyController.gzhGetCompanyInfo(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.CompanyController.subAccount(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.PersonController.*(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.SignController.*(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.UserController.modifyPwd(..)) "  +
//            "|| execution(* com.ocom.ugcapi.controller.UserController.isWeekPassword(..)) "  +
            "|| execution(* com.ocom.ugcapi.controller.RoomPersonController.*(..)) "  +
            "|| execution(* com.ocom.ugcapi.controller.OrderMealPlanController.*(..)) "  +
            "|| execution(* com.ocom.ugcapi.controller.OrderPageController.*(..)) "  +
            "|| execution(* com.ocom.ugcapi.controller.MjRecodeController.*(..)) "  +
            "|| execution(* com.ocom.ugcapi.controller.UserAuthController.*(..)) "  +
            "|| execution(* com.ocom.ugcapi.controller.LdLeaveApplyController.*(..))  " +
            "|| execution(* com.ocom.ugcapi.controller.UserController.UserInfo(..)) " +
            "|| execution(* com.ocom.ugcapi.controller.FeeDataController.*(..)) " +
            "|| execution(* com.ocom.ugcapi.controller.RepairPayController.*(..)) " +
            "|| execution(* com.ocom.ugcapi.controller.VideoPhoneController.*(..))" +
            "|| execution(* com.ocom.ugcapi.controller.XfMealLeaveController.*(..))" +
            "|| execution(* com.ocom.ugcapi.controller.GzhApplyController.*(..))" +
            "|| execution(* com.ocom.ugcapi.controller.SchoolWifiController.*(..))")
    public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {

        // 类名
        String className = pjp.getTarget().getClass().getName();
        //方法名
        String methodName = pjp.getSignature().getName();


        Map<String,Object> reqParam =null;
        String url ="";
        String machno="";
        try {

            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

            Object[] args = pjp.getArgs();

            JSONObject jsonObject= null;
            for (int i = 0; i < args.length; i++) {
                Object object=args[i];
                if (object instanceof HttpServletRequest || object instanceof HttpServletResponse) {
                    continue;
                }
                jsonObject=JSONObject.parseObject(JSONObject.toJSONString(object));
            }

            if(jsonObject==null){
                return ResultUtil.error(ResultEnum.Err_3042);
            }

            String token = jsonObject.getString("token");
            if(CommonUtil.isNull(token)){
                token = request.getHeader("token");
            }

            if(CommonUtil.isNull(token)){
                return ResultUtil.error(ResultEnum.Err_3042);
            }

            GzhUserInfo userInfo = null;
            Gson gson = new Gson();
            try {
                String userStr  = RSAHelper.decipher(token, RsaConfig.privateKey);
                if(userStr == null){
                    log.info("Pay-token异常 100 【{}】 ", token);
                    return ResultUtil.error(ResultEnum.Err_3042);
                }
                userInfo = gson.fromJson(userStr,GzhUserInfo.class);
            } catch (Exception e) {
                log.info("Pay-token异常 2 【{}】 ", e);
                return ResultUtil.error(ResultEnum.Err_3042);
            }


            Object tokenRedis = redisUtil.get("gzhToken:" + userInfo.getComId()+":"+userInfo.getPId());
            if (tokenRedis == null) {
                return ResultUtil.error(ResultEnum.Err_4028);
            }

            //判断随机数是否一致
            GzhUserInfo userInfo1 = JSON.parseObject((String) tokenRedis,GzhUserInfo.class);

            if(!userInfo1.getLoginSecret().equals(userInfo.getLoginSecret())){
                return ResultUtil.error(ResultEnum.Err_4028);
            }

            if(!methodName.equals("modifyPwd") && !methodName.equals("UserInfo")){
                //密码等级低
                if(!userInfo.getPasswordCorrect()){
                    return ResultUtil.error(ResultEnum.Err_3050);
                }
            }

            //判断appName  登录异常  与缓存appName不一致
            if(userInfo1.getAppName()!=null  && userInfo.getAppName()!=null){
                if(!userInfo1.getAppName().equals(userInfo.getAppName())){
                    userInfo.setStatus(1);
                }
            }

            Object obj = pjp.proceed(agrValue(args,userInfo));

            log.info("【系统日志】【ugcapi】管理员【{}】控制器【{}】方法【{}】参数【{}】返回【{}】",userInfo1.getPId(),className,methodName,jsonObject,obj);

            return obj;
        }catch (Exception e){
            log.info("请求URL:,切面异常:【{}】",e);
            return ResultUtil.error(ResultEnum.Err_4014);
        }
    }


    private Object[] agrValue(Object[] _obj,GzhUserInfo userInfo) throws Exception{
        for (Object obj : _obj) {
            agrMapValue(obj,userInfo);
        }
        return _obj;
    }

    private Object agrMapValue(Object _obj,GzhUserInfo userInfo) throws Exception{
        Map<String,Object> map = (Map<String,Object>) _obj;
        map.put("userInfo",userInfo);
        return map;
    }

}
